package cn.geminis.crypto.csp.parameter;

import cn.geminis.crypto.core.key.PublicKey;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.DEROctetString;
import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.asn1.DERSequenceGenerator;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.crypto.CipherParameters;

import java.io.ByteArrayOutputStream;
import java.io.IOException;

/**
 * @author Allen
 */
public class CalcAgreementCipherParameters implements CipherParameters {

    private byte[] id;
    private PublicKey publicKey;
    private PublicKey tempPublicKey;

    public CalcAgreementCipherParameters(byte[] id, PublicKey publicKey, PublicKey tempPublicKey) {
        this.id = id;
        this.publicKey = publicKey;
        this.tempPublicKey = tempPublicKey;
    }

    public CalcAgreementCipherParameters(byte[] data) {
        try {
            ASN1Sequence sequence = (ASN1Sequence) DERSequence.fromByteArray(data);
            this.id = DEROctetString.getInstance(sequence.getObjectAt(0)).getOctets();
            SubjectPublicKeyInfo publicKeyInfo = SubjectPublicKeyInfo.getInstance(sequence.getObjectAt(1));
            SubjectPublicKeyInfo tempPublicKeyInfo = SubjectPublicKeyInfo.getInstance(sequence.getObjectAt(2));
            this.publicKey = new PublicKey(publicKeyInfo);
            this.tempPublicKey = new PublicKey(tempPublicKeyInfo);
        } catch (IOException e) {
            throw new RuntimeException("解析密钥协商计算参数错误", e);
        }
    }

    public byte[] getId() {
        return id;
    }

    public PublicKey getPublicKey() {
        return publicKey;
    }

    public PublicKey getTempPublicKey() {
        return tempPublicKey;
    }

    public byte[] encode() {
        try (ByteArrayOutputStream stream = new ByteArrayOutputStream()) {
            DERSequenceGenerator generator = new DERSequenceGenerator(stream);
            generator.addObject(new DEROctetString(this.id));
            generator.addObject(this.publicKey.getSubjectPublicKeyInfo());
            generator.addObject(this.tempPublicKey.getSubjectPublicKeyInfo());
            generator.close();
            return stream.toByteArray();
        } catch (IOException e) {
            throw new RuntimeException("密钥协商计算参数编码错误", e);
        }
    }

}
